package com.dabbo.starship.app.client;

import java.awt.Color;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import javax.swing.JFrame;

import com.dabbo.starship.client.listeners.GridViewerKeyListener;
import com.dabbo.starship.interfaces.Block;
import com.dabbo.starship.interfaces.Cell;
import com.dabbo.starship.interfaces.CellLocationInterface;
import com.dabbo.starship.interfaces.Container;
import com.dabbo.starship.interfaces.Player;
import com.dabbo.starship.interfaces.PlayerPoolInterface;
import com.dabbo.starship.interfaces.UniverseInterface;
import com.dabbo.starship.shared.CellLocation;

public class StarShipMain extends JFrame implements Runnable {

	private static final long serialVersionUID = -1155345314368648065L;

	public static final int MOVE_DOWN = 1;
	public static final int MOVE_UP = 2;
	public static final int MOVE_LEFT = 3;
	public static final int MOVE_RIGHT = 4;
	
	public static final String CLIENT_VERSION = "0.050";
	
	private Registry registry;
	private UniverseInterface universe;
	private Container cp = null;
	private PlayerPoolInterface playerPool = null;
	private Player pl;
	private RoomViewUI displayPanel;

	private GridViewUI cc;
	
	public StarShipMain() {
		
		try {
			registry = LocateRegistry.getRegistry("localhost", 3232);

			universe = (UniverseInterface) (registry.lookup("universe"));
			playerPool = (PlayerPoolInterface) (registry.lookup("pool"));

			pl = playerPool.logonPlayer("dedmonds", "password");
			
			if (pl.getContainerID() == 0) {
				System.out.println("No ship asset found, creating new one.");
				pl.setContainerID(universe.initPlayerShip(pl.getUsername()).hashCode());
			}
			
			System.out.println("container ID = " + pl.getContainerID());
			
			cp = universe.getContainer(pl.getContainerID());
			pl.setRoomID(cp.getEntryBlock());
			pl.setLocation(new CellLocation(3,4));
			
			System.out.println("Container name = " + cp.getPlayerID());
			/*
			pl = new PlayerUnit();
			pl.setActiveStatus(true);
			pl.setCommandCode("");
			pl.setContainerID(cp.hashCode());
			pl.setCredits(10000);
			pl.setHealth(100);
			pl.setLocation(new CellLocation(3,4));
			pl.setPlayerName("Dabbo");
			pl.setRoomID(cp.getEntryBlock());
			*/
			
			Block blk = cp.getBlock(pl.getRoomID());
			
			displayPanel = new RoomViewUI(blk.getCells());
			displayPanel.setPlayerPos(pl.getCoY(), pl.getCoX());
			displayPanel.setBackground(Color.BLACK);
			//displayPanel.setRoomLights(true);
			displayPanel.setLayout(null);
			displayPanel.validate();
			
			this.addKeyListener(new GridViewerKeyListener(this));
			
			getContentPane().add(displayPanel);
			
			
		} catch (RemoteException ex) {
			ex.printStackTrace();
		} catch (NotBoundException ex) {
			ex.printStackTrace();
		}

		this.setTitle("StarShip Adventure v" + CLIENT_VERSION);
		this.setSize((RoomViewUI.xSize * 9), (RoomViewUI.ySize * 9) + 20);
		this.setResizable(false);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

	public void tick() {
		// Redraw windows to account for updated information from server.
		if (cc != null && cc.getFocusableWindowState()) {
			cc.repaint();
		}
		try {
			updateDisplay();
		} catch (RemoteException ex) {
			System.out.println("Remote exception occurred.");
		}
	}
	
	public void movePlayer(int direction) throws RemoteException {
		Block blk = cp.getBlock(pl.getRoomID());
		CellLocation newPos = null;
		Cell newLoc = null;
		
		//System.out.println("Current pos y(" + pl.getCoY() + "), x(" + pl.getCoX() + ")");
		
		switch(direction) {
		case StarShipMain.MOVE_DOWN:
			if (pl.getLocation().getCoY() < 8) {
				newPos = new CellLocation(pl.getCoY() + 1, pl.getCoX());
				newLoc = blk.getCell(newPos);
			} else {
				System.out.println("Ouch! I cant go that way.");
			}
			break;
		case StarShipMain.MOVE_UP:
			if (pl.getLocation().getCoY() > 0) {
				newPos = new CellLocation(pl.getCoY() - 1, pl.getCoX());
				newLoc = blk.getCell(newPos);
			} else {
				System.out.println("Ouch! I cant go that way.");
			}
			break;
		case StarShipMain.MOVE_RIGHT:
			if (pl.getLocation().getCoX() < 8) {
				newPos = new CellLocation(pl.getCoY(), pl.getCoX() + 1);
				newLoc = blk.getCell(newPos);
			} else {
				System.out.println("Ouch! I cant go that way.");
			}
			break;
		case StarShipMain.MOVE_LEFT:
			if (pl.getLocation().getCoX() > 0) {
				newPos = new CellLocation(pl.getCoY(), pl.getCoX() - 1);
				newLoc = blk.getCell(newPos);
			} else {
				System.out.println("Ouch! I cant go that way.");
			}
			break;
		default:
			System.out.println("WARNING : Undefined movement reference! : " + direction);
		}
		if (newLoc != null && newLoc.isPassable()) {
			pl.setLocation(newPos);
			updateDisplay();
		}
	}

	public void activateCell() throws RemoteException {
		Block blk = cp.getBlock(pl.getRoomID());
		Cell currentCell = blk.getCell(pl.getLocation());

		switch (currentCell.getCellType()) {
		case Cell.CELL_DOOR:
			pl.setRoomID(currentCell.getExitBlock().hashCode());
			CellLocationInterface dab = currentCell.getExitCell();
			pl.setLocation(dab);
			System.out.println("You have entered the room : " + cp.getBlock(pl.getRoomID()).getDescription());
			updateDisplay();
			break;
		case Cell.CELL_CONSOLE:
		case Cell.CELL_POWER:
			cc = new GridViewUI(currentCell);
			cc.setVisible(true);
			break;
		default:
			System.out.println("Unknown cell type ID of " +  currentCell.getCellType());
		}
		
	}
	
	private void updateDisplay() throws RemoteException {
		this.setTitle("StarShip Adventure v" + CLIENT_VERSION + " : " + cp.getBlock(pl.getRoomID()).getDescription());
		displayPanel.setRoomLights(cp.getBlock(pl.getRoomID()).isBlockLit());
		displayPanel.setPlayerPos(pl.getCoY(), pl.getCoX());
		displayPanel.setGrid(cp.getBlock(pl.getRoomID()).getCells());		
		displayPanel.repaint();
	}
	
	public static void main(String[] args) {
		System.out.println("Main entered.");
		StarShipMain exec = new StarShipMain();
        javax.swing.SwingUtilities.invokeLater(exec);

        Thread th = new Thread(new TickTimer(exec));
        th.start();
        
		//System.exit(0);		
	}

	@Override
	public void run() {
		this.setVisible(true);
	}

}